import MySQLdb
import inspect
import warnings
import random
import sys
import time


_start_time_ = time.time()
_mysql_connection_ = MySQLdb.connect(host = "localhost", user = "root", db = "gtfs")
_mysql_connection_.autocommit(False)
_mysql_cursor_ = _mysql_connection_.cursor()


def execute_sql(sql, print_sql = False):
    global _mysql_cursor_
    try:
        if print_sql: log_info(sql)
        with warnings.catch_warnings(record=True) as w:
            _mysql_cursor_.execute(sql)
            if w: log_info("Warning: " + str(w[-1].message))
    except Exception, e:
        log_err(' '.join([str(e), sql]))
        raise(e)


def execute_select(sql, print_sql = False):
    global _mysql_cursor_
    execute_sql(sql, print_sql)
    return _mysql_cursor_.fetchall()


def execute_insert(table, data, print_sql = False):
    '''
    @var table: table name
    @var data: data pairs [(column1, value1), (column2, value2), ...]
    '''
    global _mysql_cursor_
    columns = []
    values = []
    for col,val in data:
        columns.append('`' + str(col) + '`')
        if val is None or val == '':
            values.append('NULL')
        else:
            values.append(repr(str(val)))
    sql = "INSERT INTO %s(%s) VALUES(%s)" % (table, ','.join(columns), ','.join(values))
    execute_sql(sql, print_sql)
    return _mysql_cursor_.lastrowid


def log_info(msg):
    caller_stack = inspect.stack()[1]
    caller_module = caller_stack[1].split('\\')[-1].split('.')[0]
    caller_func = caller_stack[3]
    caller = caller_module + '/' + caller_func
    cur_time = time.time() - _start_time_
    output_str = "[%.3f %s]: %s" % (cur_time, caller, str(msg))
    print >> sys.stderr, output_str


def log_err(msg):
    caller_stack = inspect.stack()[1]
    caller_module = caller_stack[1].split('\\')[-1].split('.')[0]
    caller_func = caller_stack[3]
    caller = caller_module + '/' + caller_func
    cur_time = time.time() - _start_time_
    output_str = "[%.3f %s Error!]: %s" % (cur_time, caller, str(msg))
    print >> sys.stderr, output_str


def LOG2(x):
    L, R = 0, 64
    while L < R:
        M = (L + R) >> 1
        if (x >> M) > 0: L = M + 1
        else: R = M
    return L - 1


def pack_ids(dataset_id, item_id):
    mock_dataset = 0xFFF00000
    mock_item = 0x000FFFFF
    return ((dataset_id << 20) & mock_dataset) | (item_id & mock_item)


def unpack_ids(packed_id):
    mock_dataset = 0xFFF00000
    mock_item = 0x000FFFFF
    dataset_id = (packed_id & mock_dataset) >> 20
    item_id = packed_id & mock_item
    return int(dataset_id), int(item_id) 

